package com.skyline.spot.controller;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import net.imagine.core.ResultState;
import net.imagine.core.engine.ImageEngine;
import net.imagine.provider.skyline.ImageResizeResult;
import net.imagine.provider.skyline.LocalImageResizeTask;
import net.imagine.provider.skyline.MultipartImageResizeTask;
import net.imagine.provider.skyline.SkylineImageResizeTask;

import org.apache.commons.io.FilenameUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.RedirectView;

import com.skyline.base.controller.BaseController;
import com.skyline.base.exception.NotLoginException;
import com.skyline.base.type.Authority;
import com.skyline.base.type.SpotRefrenceType;
import com.skyline.common.bean.Page;
import com.skyline.common.util.Constant;
import com.skyline.common.util.ViewPaths;
import com.skyline.common.util.WebHelper;
import com.skyline.spot.model.Spot;
import com.skyline.spot.model.SpotRefrence;
import com.skyline.spot.service.SpotRefrenceService;
import com.skyline.spot.service.SpotService;
import com.skyline.user.model.User;
import com.skyline.wo.model.Album;
import com.skyline.wo.model.Article;
import com.skyline.wo.model.Photo;
import com.skyline.wo.service.AlbumService;
import com.skyline.wo.service.ArticleService;

@RequestMapping("/spot/ref")
@Controller
public class SpotRefController extends BaseController {
	private static final Log LOGGER = LogFactory
			.getLog(SpotRefController.class);
	@Autowired
	private SpotService spotService;
	@Autowired
	private SpotRefrenceService spotRefrenceService;
	@Autowired
	private ArticleService articleService;
	// @Autowired
	// private RatyService ratyService;

	@Autowired
	private AlbumService albumService;

	private @Value("${refrence.listrefrence.pagesize}")
	int listRefrencePageSize;

	@Autowired
	private ImageEngine imagine;
	private @Value("${imagine.localStorePath}")
	String localStorePath;
	private @Value("${imagine.baseSize1},${imagine.baseSize2}")
	int[] baseSizes;

	private @Value("${album.uploadphoto.filesize}")
	long maxSizePerFile;
	private @Value("${spot.test.pagesize}")
	int spotPageSize;

	/**
	 * 默认相册下的图片，由于该相册下的图片都是有用户单独一张or几张递交的refrence，而不是一整个Album，故有refrence保存，
	 * 而不用photo
	 * 
	 * @param spotId
	 * @param page
	 * @return
	 */
	/*
	 * @RequestMapping(value = "/{spotId}/defaultalbum", method =
	 * RequestMethod.GET) public ModelAndView getPhotosFromDefaultAlbumRequest(
	 * 
	 * @PathVariable("spotId") Long spotId, Page page) { ModelAndView mav = new
	 * ModelAndView(); List<SpotRefrence> refrenceList = spotRefrenceService
	 * .getRefrencesBySpotIdAndType(spotId, SpotRefrenceType.PHOTO, page);
	 * mav.addObject("refrenceList", refrenceList); return mav; }
	 */
	/**
	 * 用于对spot快速上传图片，即photo refrence，保存方式为refrence not photo
	 * 
	 * @param spotId
	 * @param page
	 * @return
	 */
	/*
	 * @RequestMapping(value = "/{spotId}/defaultalbum", method =
	 * RequestMethod.POST) public ModelAndView postPhotosToDefaultAlbumRequest(
	 * 
	 * @PathVariable("spotId") Long spotId, Page page) { ModelAndView mav = new
	 * ModelAndView();
	 * 
	 * return mav; }
	 */
	/**
	 * 直接递交照片ref
	 * 
	 * @param spotId
	 * @return
	 */
	@RequestMapping(value = "/{spotId}/photo/new", method = RequestMethod.GET)
	public ModelAndView newAlbumRefToSpotRequest(
			@PathVariable("spotId") Long spotId) {
		User user = (User) WebHelper.getSessionAttribute(null,
				Constant.SESSION_USER);
		ModelAndView mav = new ModelAndView();
		if (user == null) {
			throw new NotLoginException("上传照片必须登录");
		}
		Spot spot = spotService.getSpot(spotId);
		if (spot == null) {
			mav.setViewName(ViewPaths.SPOT_NOTFOUND);
			return mav;
		}
		Album album = new Album();
		album.setAlbumName(spot.getName());
		album.setPlace(spot.getCity());
		album.setDescription(spot.getName());
		album.setAuthority(Authority.PUBLIC);
		album = albumService.createAlbum(user, album);
		mav.addObject("album", album);
		mav.addObject("spotId", spot.getId());
		mav.setViewName(ViewPaths.SOPTREF_NEWALBUMREF);
		return mav;
	}

	private List<ImageResizeResult> processResizeResult(
			List<ImageResizeResult> results, StringBuilder message) {
		List<ImageResizeResult> filesInfo = new ArrayList<ImageResizeResult>();
		for (int i = 0; i < results.size(); i++) {
			ImageResizeResult result = results.get(i);
			ResultState state = result.getResultState();
			switch (state) {
			case SUCCESS:
				filesInfo.add(result);
				break;
			case NOT_IMAGE:
				message.append("上传图片" + result.getOriginalFilename()
						+ "失败，失败原因：图片格式不支持。<br/>");
				break;
			default:
				message.append("上传图片" + result.getOriginalFilename()
						+ "失败。<br/>");
				break;
			}
		}
		return filesInfo;
	}

	@SuppressWarnings("rawtypes")
	private List<SkylineImageResizeTask> prepareResizeTask(List files,
			long userId, long albumId, StringBuilder message) {
		if (files == null || files.isEmpty()) {
			return null;
		}
		boolean isLocal = !(files.get(0) instanceof MultipartFile);
		List<SkylineImageResizeTask> tasks = new ArrayList<SkylineImageResizeTask>(
				files.size());
		for (Object file : files) {
			long fileSize = 0L;
			String filename = null;
			SkylineImageResizeTask task;
			if (isLocal) {
				File localFile = (File) file;
				fileSize = localFile.length();
				filename = FilenameUtils.getName(localFile.getAbsolutePath());
			} else {
				MultipartFile multipartFile = (MultipartFile) file;
				fileSize = multipartFile.getSize();
				filename = multipartFile.getOriginalFilename();
			}
			if (fileSize == 0) {
				continue;
			}
			if (fileSize > maxSizePerFile) {
				message.append("上传图片" + filename + "失败，失败原因：图片太大。\n");
				continue;
			}
			if (isLocal) {
				File localFile = (File) file;
				task = new LocalImageResizeTask(localFile.getAbsolutePath(),
						baseSizes);
			} else {
				MultipartFile multipartFile = (MultipartFile) file;
				task = new MultipartImageResizeTask(multipartFile, baseSizes,
						null, false);
			}
			task.setUserId(userId);
			task.setAlbumId(albumId);
			tasks.add(task);
		}

		return tasks;
	}

	/**
	 * 
	 * @param ownerId
	 * @param albumId
	 * @param files
	 * @return
	 */
	@SuppressWarnings("unchecked")
	@RequestMapping(value = "/buploadok/{ownerId}/{albumId}", method = RequestMethod.POST)
	public @ResponseBody
	Map<String, Object> batchUploadSpotOk(
			@PathVariable("ownerId") Long ownerId,
			@PathVariable("albumId") Long albumId,
			@RequestParam("files") String files) {
		Map<String, Object> result = new HashMap<String, Object>();
		User user = (User) WebHelper.getSessionAttribute(null,
				Constant.SESSION_USER);
		if (user == null) {
			result.put("success", Boolean.FALSE);
			result.put("errmsg", "压缩图片必须");
			result.put("logined", Boolean.FALSE);
			return result;
		} else {
			result.put("logined", Boolean.TRUE);
		}
		String[] filesPath = files.split("\\|");
		List<File> localFiles = new ArrayList<File>();
		for (String filePath : filesPath) {
			if (!StringUtils.hasLength(filePath)) {
				continue;
			}
			File localFile = new File(filePath);
			localFiles.add(localFile);
		}
		if (localFiles.isEmpty()) {
			result.put("success", Boolean.FALSE);
			result.put("errmsg", "没有找到需要压缩的文件！");
			return result;
		}
		StringBuilder message = new StringBuilder();
		List<SkylineImageResizeTask> tasks = prepareResizeTask(localFiles,
				user.getId(), albumId, message);
		if (tasks == null || tasks.isEmpty()) {
			result.put("success", Boolean.FALSE);
			result.put("errmsg", "没有找到需要压缩的文件！");
			return result;
		}

		List<ImageResizeResult> results = imagine.processImage(localStorePath,
				tasks);
		List<ImageResizeResult> filesInfo = processResizeResult(results,
				message);

		Album album = null;
		try {
			album = albumService.getAlbumForChange(albumId, user.getId());
		} catch (Exception e) {
			LOGGER.warn("获取相册失败", e);
			result.put("success", Boolean.FALSE);
			result.put("errmsg", "没有找到对应相册，压缩图片失败！");
			return result;

		}
		List<Photo> photos = null;

		if (!filesInfo.isEmpty()) {
			photos = albumService.createPhotos(user, album, filesInfo);
		}
		albumService.changeAlbumCover(user.getId(), album.getId(), photos
				.get(0).getSmallFile(), photos.get(0).getExt());

		Map<Long, List<Photo>> filesMap = (Map<Long, List<Photo>>) WebHelper
				.getSessionAttribute(null, Constant.SESSION_UPLOAD_OK_FILES);
		if (filesMap == null) {
			filesMap = new HashMap<Long, List<Photo>>();
		}
		filesMap.put(album.getId(), photos);
		WebHelper.setSessionAttribute(null, Constant.SESSION_UPLOAD_OK_FILES,
				filesMap);

		if (StringUtils.hasLength(message)) {// 存在错误
			result.put("success", Boolean.FALSE);
			result.put("errmsg", message);
		} else {
			result.put("success", Boolean.TRUE);
			result.put("errmsg", "压缩图片成功！");
		}
		return result;
	}

	@RequestMapping(value = "/uploadok/{ownerId}/{albumId}", method = RequestMethod.GET)
	public ModelAndView newAlbumRefUploadOk(
			@PathVariable("ownerId") Long ownerId,
			@PathVariable("albumId") Long albumId) {
		User user = (User) WebHelper.getSessionAttribute(null,
				Constant.SESSION_USER);
		if (user == null) {
			throw new NotLoginException("添加REF必须登录");
		}
		ModelAndView mav = new ModelAndView(ViewPaths.SPOTREF_NEWALBUMREFOK);
		Spot spot = spotService.getSpot(ownerId);
		if (spot == null) {
			mav.setViewName(ViewPaths.SPOT_NOTFOUND);
		}

		mav.addObject("spotInfo", spot);
		mav.addObject("spotId", ownerId);
		mav.addObject("albumId", albumId);
		// WebHelper.saveToken(request);
		return mav;
	}

	@RequestMapping(value = "/uploadok/{ownerId}/{albumId}", method = RequestMethod.POST)
	public ModelAndView newAlbumRefToSpotRequestOK(Long spotId, Long albumId,
			String refTitle, String refrenceDigest) {
		User user = (User) WebHelper.getSessionAttribute(null,
				Constant.SESSION_USER);
		ModelAndView mav = new ModelAndView();
		if (user == null) {
			throw new NotLoginException("添加REF必须登录");
		}
		Spot spot = spotService.getSpot(spotId);

		if (spot == null) {
			mav.setViewName(ViewPaths.SPOT_NOTFOUND);
			return mav;
		}
		Album album = albumService.getAlbumById(albumId);
		if (album == null) {
			mav.setViewName(ViewPaths.SPOT_NOTFOUND);
			return mav;
		}
		Long returnRefId = spotRefrenceService.postToSpot(album.getId(),
				album.getCover() + "." + album.getCoverExt(), refTitle,
				refrenceDigest, SpotRefrenceType.ALBUM, spotId, spot.getName(),
				spot.getPortrait(), user.getId(), user.getNickname(),
				user.getPortrait(), user.getEmail());
		if (returnRefId == 0 || returnRefId == null) {
			mav.setViewName(ViewPaths.SPOT_NOTFOUND);
			return mav;
		}
		String url = buildRecirectPath("/spot/" + spotId);
		mav.setView(new RedirectView(url));
		return mav;
	}

	public ModelAndView newTxtRefToSpotRequest() {
		return null;

	}

	/**
	 * 用于为spot添加ref，refType分为album，article等，可以从自己的相册或
	 * 日志列表选择已有的添加到ref，也可以直接新建，新建之后也将根据type类型分别 在用户的相册或日志下添加该相册，照片，或日志
	 * 
	 * @param spotId
	 * @param page
	 * @return
	 */
	@RequestMapping(value = "/{spotId}/postref/{refType}", method = RequestMethod.GET)
	public ModelAndView postRefrenceToSpotRequest(
			@PathVariable("spotId") Long spotId,
			@PathVariable("refType") String refType) {
		User user = (User) WebHelper.getSessionAttribute(null,
				Constant.SESSION_USER);
		ModelAndView mav = new ModelAndView();
		if (user == null) {
			mav.setViewName(ViewPaths.USER_LOGIN);
			return mav;
		}
		Spot spotInfo = spotService.getSpot(spotId);
		mav.addObject("spotInfo", spotInfo);
		Page page = new Page();
		page.setSize(listRefrencePageSize);
		if (refType.equals("ALBUM")) {
			List<Album> albumList = albumService
					.listAlbumsOfUserWithoutPortrait(user.getId(),
							user.getId(), Authority.PUBLIC, page);
			mav.addObject("albumList", albumList);
			mav.setViewName(ViewPaths.SPOTREFRENCE_ADD);
			return mav;
		}
		if (refType.equals("NOTE")) {

		}

		return mav;
	}

	@RequestMapping(value = "/{spotId}/add", method = RequestMethod.POST)
	public ModelAndView postRefrenceToSpotSubmit(Long spotId, String spotName,
			String spotPortrait, Long refrenceId, String refrencePortrait,
			String refrenceTitle, String refrenceDigest,
			SpotRefrenceType refrenceType) {
		ModelAndView mav = new ModelAndView();
		try {
			User user = (User) WebHelper.getSessionAttribute(null,
					Constant.SESSION_USER);
			if (user == null) {
				mav.setViewName(ViewPaths.USER_LOGIN);
				return mav;
			}
			Long returnRefId = spotRefrenceService.postToSpot(refrenceId,
					refrencePortrait, refrenceTitle, refrenceDigest,
					refrenceType, spotId, spotName, spotPortrait, user.getId(),
					user.getNickname(), user.getPortrait(), user.getEmail());
			if (returnRefId != null && returnRefId != 0) {
				/**
				 * 做成ajax方式的递交
				 */
				// map.put("PostSuccess", true);
				String url = buildRecirectPath("/spot/" + spotId);
				mav.setView(new RedirectView(url));
				return mav;
			}
			mav.setViewName(ViewPaths.SPOTREFRENCE_ADD);
			return mav;
		} catch (Exception e) {
			ModelAndView v = new ModelAndView(ViewPaths.USER_LOGIN);
			return v;
		}

	}

	/**
	 * 查看ref
	 * 
	 * @param spotId
	 * @param refrenceType
	 * @param page
	 * @return
	 */
	@RequestMapping(value = "/{spotId}/{refrenceType}/list", method = RequestMethod.GET)
	public ModelAndView querySpotRefrence(@PathVariable("spotId") Long spotId,
			@PathVariable("refrenceType") SpotRefrenceType refrenceType, Page page) {
		List<SpotRefrence> refrenceList = null;
		page.setSize(listRefrencePageSize);
		if(refrenceType==SpotRefrenceType.ALBUM)
		{
			refrenceList = spotRefrenceService.getRefrencesBySpotIdAndType(
					spotId, SpotRefrenceType.ALBUM, page);
		}
		else if (refrenceType==SpotRefrenceType.STRATEGY) {
			refrenceList = spotRefrenceService.getRefrencesBySpotIdAndType(
					spotId, SpotRefrenceType.STRATEGY, page);
		} else if (refrenceType==SpotRefrenceType.TRAVELNOTE) {
			refrenceList = spotRefrenceService.getRefrencesBySpotIdAndType(
					spotId, SpotRefrenceType.TRAVELNOTE, page);
		}
		ModelAndView v = new ModelAndView(ViewPaths.SPOTREFRENCE_LIST);
		v.addObject("refrenceList", refrenceList);
		return v;
	}

	/**
	 * 查看详细信息，通过refrence中的refrenceID获得详细数据
	 * 
	 * @param id
	 * @return
	 */
	@RequestMapping(value = "/{spotId}/{id}", method = RequestMethod.GET)
	public ModelAndView querySpotRefrenceDetail(@PathVariable("id") Long id,
	@PathVariable("spotId") Long spotId) {
		ModelAndView mav = new ModelAndView();
		SpotRefrence ref = spotRefrenceService.getRefrenceById(id);
		if(ref==null)
		{
			mav.setViewName(ViewPaths.SPOT_NOTFOUND);
			return mav;
		}
		if (ref.getRefrenceType() == SpotRefrenceType.ALBUM) {
			Page page = new Page();
			page.setSize(listRefrencePageSize);
			List<Photo> photoList = albumService.listPhotosOfAlbum(
					ref.getRefrenceId(), 0, Authority.PUBLIC, page, true);
			mav.addObject("refInfo", ref);
			mav.addObject("photoList", photoList);
			mav.setViewName(ViewPaths.SPOTREFRENCE_PHOTOVIEW);
			return mav;

		} else if (ref.getRefrenceType() == SpotRefrenceType.TRAVELNOTE) {

		} else {
			Article article = articleService.getArticleById(id);
			ModelAndView v = new ModelAndView(ViewPaths.SPOTREFRENCE_DETAIL);
			v.addObject("article", article);

			return v;
		}
		return null;
	}

	@RequestMapping(value = "/{spotId}/{refrenceType}/detail", method = RequestMethod.GET)
	public ModelAndView querySpotRefrenceDetail(
			@PathVariable("refrenceType") SpotRefrenceType refrenceType,
			@PathVariable("spotId") Long spotId) {
		ModelAndView mav = new ModelAndView();
		if (refrenceType == SpotRefrenceType.ALBUM) {
			Page page = new Page();
			page.setSize(1);
			SpotRefrence spotRef = spotRefrenceService
					.getRefrencesBySpotIdAndType(spotId,
							SpotRefrenceType.ALBUM, page).get(0);
			Album album = albumService.getAlbumById(spotRef.getRefrenceId());
			List<Photo> photosList = albumService.listPhotosOfAlbum(
					album.getId(), 0, Authority.PUBLIC, page, true);
			mav.addObject("photoList", photosList);
			mav.addObject("albumInfo", album);
			mav.addObject("refInfo", spotRef);
			return mav;

		} else if (refrenceType == SpotRefrenceType.TRAVELNOTE) {

		} else {

		}
		return null;
	}

	/**
	 * Demo refrence
	 */

}
